
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include "board.h"

#define CONSOLE_BUF_SIZE 512
static uint32_t console_tx_sem = 0;

int ev_console_init(uint32_t baudrate)
{
    driv_console_uart_init(baudrate);
    return 0;
}

static void wait_tx_done(void)
{
    uint32_t flag;
    while (1)
    {
        flag = driv_disable_irq();
        uint32_t tx_sem = console_tx_sem;
        driv_enable_irq(flag);

        if (!tx_sem) {
            hw_delay_us(5);
        } else {
            break;
        }
    }
    flag = driv_disable_irq();
    console_tx_sem = 0;
    driv_enable_irq(flag);
}

void ev_printf(const char *format, ...)
{
    static char console_tx_buf[CONSOLE_BUF_SIZE * 2] __attribute__((aligned(8)));
    va_list args;
    uint32_t length;

    va_start(args, format);
    vsnprintf(&console_tx_buf[CONSOLE_BUF_SIZE],
                CONSOLE_BUF_SIZE - 1,
                format,
                args
    );
    length = strlen(&console_tx_buf[CONSOLE_BUF_SIZE]);
    va_end(args);

    uint32_t tx_len = 0;
    for (uint32_t i = 0; i < length; i ++) {
        if (console_tx_buf[i + CONSOLE_BUF_SIZE] == '\n') {
            console_tx_buf[tx_len ++] = '\r';
        }
        console_tx_buf[tx_len ++] = console_tx_buf[i + CONSOLE_BUF_SIZE];
    }
    if (tx_len > 0) {
        driv_console_uart_write((uint8_t *)console_tx_buf, tx_len);
        wait_tx_done();
    }
}

void driv_console_uart_tx_cb(void)
{
    uint32_t flag = driv_disable_irq();
    console_tx_sem = 1;
    driv_enable_irq(flag);
}

void driv_console_uart_rx_cb(uint8_t c)
{
    /* do nothing */
    (void)c;
}
